<!--
Copyright (C) 2016-2023 Jones Magloire @Joxit

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<tag-table>
  <confirm-delete-image
    opened="{ state.confirmDeleteImage }"
    on-click="{ onConfirmDeleteImageClick }"
    registry-url="{ props.registryUrl }"
    on-notify="{ props.onNotify }"
    on-authentication="{ props.onAuthentication }"
    tags="{ props.tags }"
    to-delete="{ state.toDelete }"
    is-registry-secured="{ props.isRegistrySecured }"
    on-image-deleted="{ props.onImageDeleted }"
  ></confirm-delete-image>
  <material-card class="taglist">
    <table style="border: none">
      <thead>
        <tr>
          <th
            class="creation-date { (state.desc && state.orderType === 'date') ? 'material-card-th-sorted-descending' : 'material-card-th-sorted-ascending' }"
            onclick="{() => onPageReorder('date') }"
          >
            Creation date
          </th>
          <th
            class="image-size { (state.desc && state.orderType === 'size') ? 'material-card-th-sorted-descending' : 'material-card-th-sorted-ascending' }"
            onclick="{() => onPageReorder('size') }"
          >
            Size
          </th>
          <th id="image-content-digest-header" if="{ props.showContentDigest }">Content Digest</th>

          <th
            id="image-tag-header"
            class="{ props.asc ? 'material-card-th-sorted-ascending' : 'material-card-th-sorted-descending' }"
            onclick="{ onReverseOrder }"
          >
            Tag
          </th>
          <th class="architectures">Arch</th>
          <th class="show-tag-history" if="{ props.showTagHistory }">History</th>
          <th
            class="remove-tag { state.toDelete.size > 0 && !state.singleDeleteAction ? 'delete' : '' }"
            if="{ props.isImageRemoveActivated }"
          >
            <material-checkbox
              class="indeterminate"
              checked="{ state.multiDelete }"
              if="{ state.toDelete.size === 0 || state.singleDeleteAction }"
              title="Toggle multi-delete. Alt+Click to select all tags."
              onChange="{ onRemoveImageHeaderChange }"
            >
            </material-checkbox>
            <material-button
              if="{ state.toDelete.size > 0 && !state.singleDeleteAction }"
              waves-center="true"
              color="inherit"
              text-color="var(--neutral-background)"
              waves-color="var(--hover-background)"
              title="This will delete selected images."
              onClick="{ deleteImages }"
              icon
            >
              <i class="material-icons">delete</i>
            </material-button>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr each="{ image in getPage(props.tags, props.page) }" if="{ matchSearch(props.filterResults, image.tag) }">
          <td class="creation-date">
            <image-date image="{ image }"></image-date>
          </td>
          <td class="image-size">
            <image-size image="{ image }"></image-size>
          </td>
          <td if="{ props.showContentDigest }">
            <image-content-digest image="{ image }"></image-content-digest>
            <copy-to-clipboard
              target="digest"
              image="{ image }"
              pull-url="{ props.pullUrl }"
              on-notify="{ props.onNotify }"
            ></copy-to-clipboard>
          </td>
          <td>
            <image-tag image="{ image }"></image-tag>
            <copy-to-clipboard
              target="tag"
              image="{ image }"
              pull-url="{ props.pullUrl }"
              on-notify="{ props.onNotify }"
            ></copy-to-clipboard>
          </td>
          <td class="architectures">
            <architectures image="{ image }"></architectures>
          </td>
          <td class="show-tag-history" if="{ props.showTagHistory }">
            <tag-history-button image="{ image }"></tag-history-button>
          </td>
          <td if="{ props.isImageRemoveActivated }" class="remove-tag">
            <remove-image
              multi-delete="{ state.multiDelete }"
              image="{ image }"
              registry-url="{ props.registryUrl }"
              handleCheckboxChange="{ onRemoveImageChange }"
              checked="{ state.toDelete.has(image) }"
              on-notify="{ props.onNotify }"
              on-authentication="{ props.onAuthentication }"
            ></remove-image>
          </td>
        </tr>
      </tbody>
    </table>
  </material-card>
  <script>
    import { getPage } from '../../scripts/utils';
    import ImageDate from './image-date.riot';
    import ImageSize from './image-size.riot';
    import ImageTag from './image-tag.riot';
    import ImageContentDigest from './image-content-digest.riot';
    import CopyToClipboard from './copy-to-clipboard.riot';
    import TagHistoryButton from './tag-history-button.riot';
    import RemoveImage from './remove-image.riot';
    import Architectures from './architectures.riot';
    import { matchSearch } from '../search-bar.riot';
    import ConfirmDeleteImage from '../dialogs/confirm-delete-image.riot';
    const ACTION_CHECK_TO_DELETE = 'CHECK';
    const ACTION_UNCHECK_TO_DELETE = 'UNCHECK';
    const ACTION_DELETE_IMAGE = 'DELETE';

    export default {
      components: {
        ImageDate,
        ImageSize,
        ImageTag,
        ImageContentDigest,
        CopyToClipboard,
        RemoveImage,
        TagHistoryButton,
        ConfirmDeleteImage,
        Architectures,
      },
      onBeforeMount(props) {
        this.state = {
          toDelete: new Set(),
          multiDelete: false,
          page: props.page,
        };
      },
      onBeforeUpdate(props, state) {
        if (state.page !== props.page) {
          state.toDelete.clear();
        }
        state.page = props.page;
      },
      deleteImages() {
        this.update({
          confirmDeleteImage: true,
        });
      },
      onConfirmDeleteImageClick() {
        if (this.state.singleDeleteAction) {
          this.state.toDelete.clear();
        }
        this.update({
          singleDeleteAction: false,
          confirmDeleteImage: false,
        });
      },
      onRemoveImageHeaderChange(event) {
        if (event.altKey === true) {
          const tags = getPage(this.props.tags, this.props.page);
          tags
            .filter((image) => matchSearch(this.props.filterResults, image.tag))
            .forEach((tag) => this.state.toDelete.add(tag));
          this.update({
            multiDelete: true,
            toDelete: this.state.toDelete,
            selectedImage: undefined,
          });
        } else {
          this.update({
            multiDelete: event.target.checked,
            selectedImage: undefined,
          });
        }
      },
      onRemoveImageChange(action, image, shiftKey) {
        let confirmDeleteImage = false;
        let singleDeleteAction = false;
        let selectedImage = undefined;
        switch (action) {
          case ACTION_CHECK_TO_DELETE: {
            this.state.toDelete.add(image);
            if (shiftKey) {
              selectedImage = this.supportShiftKey(image, true);
            }
            break;
          }
          case ACTION_UNCHECK_TO_DELETE: {
            this.state.toDelete.delete(image);
            if (shiftKey) {
              selectedImage = this.supportShiftKey(image, false);
            }
            break;
          }
          case ACTION_DELETE_IMAGE: {
            this.state.toDelete.clear();
            this.state.toDelete.add(image);
            confirmDeleteImage = true;
            singleDeleteAction = true;
          }
        }
        this.update({
          toDelete: this.state.toDelete,
          confirmDeleteImage,
          singleDeleteAction,
          selectedImage,
        });
      },
      supportShiftKey(selectedImage, addOrRemove) {
        if (!this.state.selectedImage) {
          return selectedImage;
        } else {
          let shouldChange = false;
          const tags = this.getPage(this.props.tags, this.props.page);
          tags
            .filter((image) => {
              if (image == this.state.selectedImage || image == selectedImage) {
                shouldChange = !shouldChange;
                return true;
              }
              return shouldChange;
            })
            .forEach((image) => {
              if (addOrRemove) {
                this.state.toDelete.add(image);
              } else {
                this.state.toDelete.delete(image);
              }
            });
          return undefined;
        }
      },
      onReverseOrder() {
        this.state.orderType = null;
        this.state.desc = false;
        this.props.onReverseOrder();
      },
      onPageReorder(type) {
        this.update({
          orderType: type,
          desc: (this.state.orderType && this.state.orderType !== type) || !this.state.desc,
        });
      },
      getPage(tags, page) {
        const sortedTags = getPage(tags, page, this.props.tagsPerPage);
        if (this.state.orderType === 'date') {
          sortedTags.sort((e1, e2) =>
            !this.state.desc
              ? (e2.creationDate?.getTime() || 0) - (e1.creationDate?.getTime() || 0)
              : (e1.creationDate?.getTime() || 0) - (e2.creationDate?.getTime() || 0)
          );
        } else if (this.state.orderType === 'size') {
          sortedTags.sort((e1, e2) => (!this.state.desc ? e2.size - e1.size : e1.size - e2.size));
        }
        return sortedTags;
      },
      matchSearch,
    };
    export { ACTION_CHECK_TO_DELETE, ACTION_UNCHECK_TO_DELETE, ACTION_DELETE_IMAGE };
  </script>
  <style>
    tag-table table th.architectures {
      text-align: center;
    }
  </style>
</tag-table>
